<template>
  <el-cascader
    v-model="addrValue"
    placeholder="请选择地址"
    :props="addressProps"
    :options="addrOptions"
    @change="onChange"
    filterable
    clearable
  />
</template>

<script setup lang="ts" name="singleAddress">
  import { ref, onBeforeMount, watch } from 'vue'
  import type { CascaderProps } from 'element-plus'
  // Api
  import { getPrimaryAddress } from '../../api/address'

  // 接收传参数对象
  const prop = defineProps({
    // 回显地址对象
    address: {
      type: Object,
      default: {
        province: '', // 省
        city: '', // 市
        area: '', // 县/区
        town: '', // 镇
      },
    },
    checkStrictly: {
      type: Boolean,
      default: false,
    },
  })

  // 接收组件传递过来的方法
  const emit = defineEmits(['value-change'])

  const addrValue = ref([]) // 地址选项值
  const addrOptions = ref([]) // 地址对象
  const hasAddrSource = ref(false) // 是否有地址源
  const hasEchoAddr = ref(false) // 是否有回显地址
  const selectAddr = ref({
    province: '', // 省
    city: '', // 市
    area: '', // 县/区
    town: '', // 镇
  })

  // 地址配置项
  const addressProps: CascaderProps = {
    value: 'code',
    label: 'name',
    children: 'children',
    expandTrigger: 'click' as const,
    checkStrictly: prop.checkStrictly,
  }

  // 地址点击改变事件
  const onChange = (val) => {
    if (val) {
      addrValue.value = val
      emit('value-change')
    }
  }

  // 地址回显方法
  const addressEcho = async () => {
    if (!prop.address.province) {
      return
    }
    hasEchoAddr.value = false
    addrValue.value = []
    addrOptions.value.map((pro) => {
      if (pro.name === prop.address.province) {
        addrValue.value.push(pro.code)
        pro.children.map((cit) => {
          if (cit.name === prop.address.city) {
            addrValue.value.push(cit.code)
            cit.children.map((area) => {
              if (area.name === prop.address.area) {
                addrValue.value.push(area.code)
              }
            })
          }
        })
      }
    })
  }

  // 获取一级地址
  const requestOneAddressApi = async () => {
    addrOptions.value = []
    await getPrimaryAddress().then((res) => {
      addrOptions.value = res.data.data.rows
      hasAddrSource.value = true
      if (hasEchoAddr.value) {
        addressEcho()
      }
    })
  }

  // 获取选中的地址对象
  const getSelectAddr = () => {
    if (!addrValue.value) {
      selectAddr.value = {
        province: '', // 省
        city: '', // 市
        area: '', // 县/区
        town: '', // 镇
      }
      return selectAddr.value
    }
    addrOptions.value.map((pro) => {
      if (pro.code === addrValue?.value[0]) {
        selectAddr.value.province = pro.name
        pro.children?.map((c) => {
          if (c.code === addrValue?.value[1]) {
            selectAddr.value.city = c.name
            c.children?.map((a) => {
              if (a.code === addrValue?.value[2]) {
                selectAddr.value.area = a.name
                selectAddr.value.town = ''
                return selectAddr.value
              }
            })
          }
        })
      }
    })
    return selectAddr.value
  }

  // 清除地址对象
  const clearSelectAddr = () => {
    addrValue.value = []
    selectAddr.value = {
      province: '', // 省
      city: '', // 市
      area: '', // 县/区
      town: '', // 镇
    }
  }

  // 监听地址回显
  watch(
    () => prop.address,
    () => {
      if (prop.address.province === '') {
        return
      }
      if (hasAddrSource.value) {
        addressEcho()
      } else {
        hasEchoAddr.value = true
      }
    },
    {
      immediate: true, // 加上此即可监听到第一次的值
    },
  )

  onBeforeMount(() => {
    requestOneAddressApi()
  })

  defineExpose({
    getSelectAddr,
    clearSelectAddr,
  })
</script>

<style lang="scss" scoped></style>
